package com.jackstraw.jack_base.rules.service.impl;

import com.jackstraw.jack_base.datasource.common.aspect.annotation.DataSourceNameCut;
import com.jackstraw.jack_base.datasource.common.entity.enums.DataSourceTypeEnum;
import com.jackstraw.jack_base.datasource.mybatis.base.service.impl.MyBatisServiceImpl;
import com.jackstraw.jack_base.rules.dao.database.RuleDao;
import com.jackstraw.jack_base.rules.entity.bo.ImportPackageBo;
import com.jackstraw.jack_base.rules.entity.bo.RelationRgrBo;
import com.jackstraw.jack_base.rules.entity.bo.RuleBo;
import com.jackstraw.jack_base.rules.entity.enums.ResultEnum;
import com.jackstraw.jack_base.rules.entity.mapstruct.RuleMapstruct;
import com.jackstraw.jack_base.rules.entity.po.RuleKeyPo;
import com.jackstraw.jack_base.rules.entity.po.RulePo;
import com.jackstraw.jack_base.rules.entity.po.RulePoExample;
import com.jackstraw.jack_base.rules.exception.BadRuleException;
import com.jackstraw.jack_base.rules.service.ImportPackageService;
import com.jackstraw.jack_base.rules.service.RelationRgrService;
import com.jackstraw.jack_base.rules.service.RuleService;
import com.jackstraw.jack_base.util.CollectionUtil;
import com.jackstraw.jack_base.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 规则表  service实现类
 *
 * @author zhaozhao 945514650@qq.com
 * @since version:1.0 generatorDate:2022-12-04 14:28:29
 */
@Slf4j
@DataSourceNameCut(dataSourceName = "dataBaseName1", dataSourceTypeEnum = DataSourceTypeEnum.database)
public class RuleServiceImpl
        extends MyBatisServiceImpl<RuleDao, RulePo, RuleBo, RuleKeyPo<RulePo>, RulePoExample>
        implements RuleService {


    @Autowired
    private RuleMapstruct ruleMapstructrtion;


    @Autowired
    private ImportPackageService importPackageService;

    @Autowired
    private RelationRgrService relationRgrService;

    @Override
    protected RulePoExample pe(Map<String, Object> params) {
        RulePoExample pe = super.pe(params);
        //默认查询主键
        pe.addKey(params);
        return pe;
    }


    @Override
    public RuleBo getOne(Long ruleId) {
        RuleKeyPo ruleKeyPo = new RuleKeyPo();
        ruleKeyPo.setRuleId(ruleId);
        RulePo rulePo = this.getDao().selectByPrimaryKey(ruleKeyPo);
        if (ObjectUtil.ObjectUtilByLang3.isEmpty(rulePo)) {
            throw new BadRuleException(ResultEnum.RULE_DATA_NO_FIND_BY_DATABASE);
        }

        if (Objects.equals(0, rulePo.getIsValid())) {
            throw new BadRuleException(ResultEnum.RULE_DATA_LOSE_EFFICACY);
        }
        RuleBo ruleBo = ruleMapstructrtion.bo(rulePo);
        return ruleBo;
    }

    @Override
    public RuleBo getOneAll(Long ruleId) {
        RuleBo ruleBo = this.getOne(ruleId);
        //查询对应的导入的包
        List<ImportPackageBo> importPackageBos = importPackageService.queryImportSByRuleId(ruleId);
        ruleBo.setImportPackages(importPackageBos);
        return ruleBo;
    }

    @Override
    public List<RuleBo> getAllByRuleGroupId(Long ruleGroupId) {
        List<RelationRgrBo> relationRgrBos = relationRgrService.queryByRuleGroupId(ruleGroupId);
        if (CollectionUtil.isEmpty(relationRgrBos)) {
            log.warn("通过规则组ID[{}]没有找到对应的规则关系", ruleGroupId);
            throw new BadRuleException(ResultEnum.RULE_GROUP_NO_FIND_RULES_RELATION);
        }
        List<RuleBo> ruleBos = relationRgrBos.stream()
                .collect(Collectors.toSet()).parallelStream()
                .map(relationRgrBo -> {
                    try {
                        RuleBo ruleBo = this.getOneAll(relationRgrBo.getRuleId());
                        ruleBo.setSort(relationRgrBo.getSort());
                        return ruleBo;
                    } catch (BadRuleException badRuleException) {
                        return null;
                    }
                }).filter(ruleBo -> ObjectUtil.ObjectUtilByLang3.isNotEmpty(ruleBo))
                .sorted(Comparator.comparing(RuleBo::getSort))
                .collect(Collectors.toList());
        return ruleBos;
    }

}
